package com.qf.config;

import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * 1、Java配置方式  创建交换机  创建队列   绑定 （无敌）   RabbitMq课上 强烈 Java配置
 *
 * 2、RabbitAdmin ： org.springframework.boot:spring-boot-starter-amqp:2.1.4.RELEASE  （扩展
 *    AmpqAdmin ：   org.springframework.boot:spring-boot-starter-amqp:2.2.8.RELEASE
 *        改使用 ： AmpqAdmin   动态创建交换机 队列 绑定
 * 3、注解方式   创建交换机 创建队列  绑定   （项目中使用到的）
 *
 *
 *  延迟消息：   注解方式不好用
 *              Java配置方式好用
 *
 *
 * @author lixu
 */
@Configuration  //Java配置类
public class RabbitMQConfig {


    //死信交换机
    //public static final String EXCHANGE_DEAD_LETTER = "exchange_dead_letter";
    //正常的交换机
    public static final String NORMAL_EXCHANGE = "normal_exchange";

    //死信队列
    public static final String QUEUE_DEAD_LETTER = "queue_dead_letter";
    //正常的队列
    public static final String NORMAL_QUEUE = "normal_queue";

    //死信routingkey
    public static final String ROUTINGKEY_DEAD_LETTER = "routingkey_dead_letter";
    //正常的routingkey
    public static final String NORMAL_ROUTINGKEY = "normal_routingkey";

    /**
     *  //正常的交换机   死信交换机
     */
    @Bean
    public Exchange normalExchange(){
        return ExchangeBuilder.directExchange(NORMAL_EXCHANGE).build();
    }
    /**
     *  //正常的队列
     */
    @Bean
    public Queue normalQueue(){
        return QueueBuilder.durable(NORMAL_QUEUE).build();
    }
    //死信交换机
/*    @Bean
    public Exchange deadLetterExchange(){

        return new CustomExchange(EXCHANGE_DEAD_LETTER,"direct");
    }*/

    //死信队列   局部设置时间的优先级大于全局的设置
    @Bean
    public Queue deadLetterQueue(){
        Map<String, Object> arguments = new HashMap<>();
        //过期时间  默认单位是毫秒   30*60*1000
        arguments.put("x-message-ttl",30*60*1000);// 30分钟  //全局的设置
        //发消息的时候不指定多长时间 默认就使用全局的设置  30分钟
        //发消息的时候就人为指定多长时间  （局部设置）

        //过期转发到 死信交换机
        arguments.put("x-dead-letter-exchange",NORMAL_QUEUE);
        //过期转发到 转发 死信RoutingKey
        arguments.put("x-dead-letter-routing-key",ROUTINGKEY_DEAD_LETTER);
        return QueueBuilder.durable(QUEUE_DEAD_LETTER).withArguments(arguments).build();
    }

    //绑定
    @Bean
    public Binding bindingDeadLetterQueueToNormalExchange(Queue deadLetterQueue,Exchange normalExchange){

        return BindingBuilder.bind(deadLetterQueue).to(normalExchange).with(NORMAL_ROUTINGKEY).noargs();
    }
    //绑定
    @Bean
    public Binding bindingNormalQueueToNormalExchange(Queue normalQueue,Exchange normalExchange){
        return BindingBuilder.bind(normalQueue).to(normalExchange).with(ROUTINGKEY_DEAD_LETTER).noargs();
    }



    /////////////////////////////////下面基于延迟插件的///////////////////////////////////////////////////

    public static final String DELAY_EXCHANGE = "delayed_exchange";
    public static final String DELAY_ROUTING_KEY = "#"; //通配符  主题交换机
    public static final String DELAY_QUEUE = "delayed_queue";
    /**
     * 基于插件的  队列
     */
    @Bean
    public Queue delayQueue123(){
        return QueueBuilder.durable(DELAY_QUEUE).build();
    }
    /**
     * 基于插件的  交换机
     *
     *         Type	   x-delayed-message   消息的类型
     * Features
     * arguments:
     *          x-delayed-type:	topic    交换机类型
     * durable:	true
     * messages delayed:	0
     */
    @Bean
    public Exchange delayExchange123(){
        //参数1： 交换机名称
        //参数2： 交换机中消息的类型
        // x-delayed-message : 交换机中延迟消息的类型
        Map<String, Object> arguments = new HashMap<>();
        //交换机的类型
        arguments.put("x-delayed-type","topic");
        return new CustomExchange(DELAY_EXCHANGE,
                "x-delayed-message",
                true,false,arguments);
    }

    /**
     * 绑定
     * @return
     */
    @Bean
    public Binding bindingDelayQueueToDelayExchange(Queue delayQueue123,Exchange delayExchange123){
        return BindingBuilder.bind(delayQueue123).to(delayExchange123).with(DELAY_ROUTING_KEY).noargs();
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////////////

}
